# https://capi.jiansheku.com/nationzj/enterprice/page
# 建设库企业查询接口 - JS 逆向实现

import requests
from fake_useragent import UserAgent
import hashlib
import json
import time

url = "https://capi.jiansheku.com/nationzj/enterprice/page"


# ==================== 签名算法实现 ====================

def _d(value):
    """
    处理值的序列化（对应 JS 中的 _d 函数）
    根据 JS 代码推测：将对象转为 JSON 字符串
    """
    if value is None:
        return None
    if value == "":
        return ""
    # 如果是字典或列表，转为 JSON 字符串（不带空格）
    if isinstance(value, (dict, list)):
        return json.dumps(value, separators=(',', ':'), ensure_ascii=False)
    return str(value)


def gd(data):
    """
    对字典的键进行排序（对应 JS 中的 gd 函数）
    """
    return sorted(data.keys())


def md(data):
    """
    对请求数据进行序列化（对应 JS 中的 md 函数）
    格式：key1=value1&key2=value2&
    """
    if not data:
        return ""
    # 获取排序后的键名
    sorted_keys = gd(data)
    result = ""
    # 遍历键名，拼接字符串
    for key in sorted_keys:
        value = _d(data[key])
        # 过滤 null 和空字符串
        if value is not None and value != "":
            result += f"{key}={value}&"
    return result


def fd(text):
    """
    MD5 加密函数（对应 JS 中的 fd()(text)）
    返回十六进制字符串
    """
    return hashlib.md5(text.encode('utf-8')).hexdigest()


def pd(key, data, timestamp):
    """
    签名加密函数（对应 JS 中的 pd 函数）
    公式：MD5(data + key + timestamp)
    """
    combined = str(data) + str(key) + str(timestamp)
    return fd(combined)


def generate_sign(data, timestamp):
    """
    生成最终签名：三层嵌套 MD5 加密
    对应 JS 代码：
    pd("ghaepVf6IhcHmgnk4NCTXLApxQkBcvh1",
       pd("mwMlWOdyM7OXbjzQPulT1ndRZIAjShDB",
          pd("ZuSj0gwgsKXP4fTEz55oAG2q2p1SVGKK", t, time),
          time),
       time)
    """
    # 第一步：对数据进行序列化
    t = md(data)
    # 第二步：三层嵌套 MD5 加密
    sign1 = pd("ZuSj0gwgsKXP4fTEz55oAG2q2p1SVGKK", t, timestamp)
    sign2 = pd("mwMlWOdyM7OXbjzQPulT1ndRZIAjShDB", sign1, timestamp)
    sign3 = pd("ghaepVf6IhcHmgnk4NCTXLApxQkBcvh1", sign2, timestamp)
    return sign3


# ==================== 请求参数配置 ====================

params = {
    "eid": "",
    "achievementQueryType": "and",
    "achievementQueryDto": [],
    "personnelQueryDto": {
        "queryType": "and"
    },
    "aptitudeQueryDto": {
        "queryType": "and",
        "nameStr": "",
        "aptitudeQueryType": "and",
        "businessScopeQueryType": "or",
        "filePlaceType": "1",
        "aptitudeDtoList": [
            {
                "codeStr": "",
                "queryType": "and",
                "aptitudeType": "qualification"
            }
        ],
        "aptitudeSource": "new"
    },
    "page": {
        "page": 1,
        "limit": 20,
        "field": "",
        "order": ""
    }
}

# ==================== 生成签名和请求头 ====================

# 生成时间戳（毫秒）
timestamp = int(time.time() * 1000)

# 生成签名
sign = generate_sign(params, timestamp)

# 构造请求头
headers = {
    "User-Agent": UserAgent().random,
    "Origin": "https://www.jiansheku.com",
    "Referer": "https://www.jiansheku.com/",
    "Content-Type": "application/json",
    "deviceType": "PC",
    "timestamp": str(timestamp),
    "sign": sign
}

def search_enterprise(keyword="", page=1, limit=20):
    """
    搜索企业
    :param keyword: 企业名称关键词
    :param page: 页码
    :param limit: 每页数量
    """
    params = {
        "eid": "",
        "achievementQueryType": "and",
        "achievementQueryDto": [],
        "personnelQueryDto": {
            "queryType": "and"
        },
        "aptitudeQueryDto": {
            "queryType": "and",
            "nameStr": keyword,  # 搜索关键词
            "aptitudeQueryType": "and",
            "businessScopeQueryType": "or",
            "filePlaceType": "1",
            "aptitudeDtoList": [
                {
                    "codeStr": "",
                    "queryType": "and",
                    "aptitudeType": "qualification"
                }
            ],
            "aptitudeSource": "new"
        },
        "page": {
            "page": page,
            "limit": limit,
            "field": "",
            "order": ""
        }
    }

    timestamp = int(time.time() * 1000)
    sign = generate_sign(params, timestamp)

    headers = {
        "User-Agent": UserAgent().random,
        "Origin": "https://www.jiansheku.com",
        "Referer": "https://www.jiansheku.com/",
        "Content-Type": "application/json",
        "deviceType": "PC",
        "timestamp": str(timestamp),
        "sign": sign
    }

    try:
        response = requests.post(url, headers=headers, json=params, timeout=10)
        if response.status_code == 200:
            return response.json()
        else:
            print(f"请求失败: {response.status_code}")
            return None
    except Exception as e:
        print(f"请求异常: {e}")
        return None


# 示例：搜索包含"建筑"的企业（取消注释以使用）
print("=" * 80)
keyword = ""
if keyword:
    print(f"🔍 搜索关键词：{keyword}")
else:
    print("🔍 搜索全部类型")
print("=" * 80)
result = search_enterprise(page=1, limit=20)
if result:
    print(json.dumps(result, indent=2, ensure_ascii=False))
